package agents;

import env.Enviroment;
import env.Action;
import env.Orientation;
import env.Tile;
import env.TileType;
import java.awt.Color;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.Icon;

/**
 *
 * @author orcas
 */
public abstract class Agent {

    private String name;
    private Color color;
    public int score = 0;
    //State:
    private int row,  col;
    private Orientation orientation;
    private boolean isAlive = true;
    private boolean isArmed = false;

    public Agent(String name, int row, int col, Orientation orientation, Color color) {
        this.name = name;
        this.row = row;
        this.col = col;
        this.orientation = orientation;
        this.color = color;
    }

    public boolean isLegalMove(Action move) {
        if (move == Action.left || move == Action.right) {
            return !getCurrentTile().isIce();
        } else if (move == Action.fwd) {
            return Enviroment.env.isCellFree(getForward());
        }
        return false;
    }

    public abstract Action getMove();

    public abstract Icon getIcon();

    public boolean isAlive() {
        return this.isAlive;
    }

    public void kill() {
        this.isAlive = false;
        getCurrentTile().updateIcon();
        System.out.println(this + " is dead!  on step "+Enviroment.step);
        try {
            System.in.read();
        } catch (IOException ex) {
            Logger.getLogger(Agent.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public boolean isArmed() {
        return this.isArmed;
    }

    public Enviroment getEnv() {
        return Enviroment.env;
    }

    public String getName() {
        return name;
    }

    public int getRow() {
        return row;
    }

    public Tile getCurrentTile() {
        return Enviroment.env.map[getRow()][getCol()];
    }

    public int getCol() {
        return col;
    }

    public Orientation getOrientation() {
        return this.orientation;
    }

    public Color getColor() {
        return this.color;
    }

    public int[] getForward() {
        int newCell[] = {row, col};
        switch (this.orientation) {
            case North: {
                newCell[0]--;
                break;
            }
            case East: {
                newCell[1]++;
                break;
            }
            case West: {
                newCell[1]--;
                break;
            }
            case South: {
                newCell[0]++;
                break;
            }
        }
        return newCell;
    }

    public void updatePosition(Action move) {
        if (move == Action.fwd) {
            int newCell[] = getForward();
            row = newCell[0];
            col = newCell[1];
        } else {
            orientation = Orientation.turn(orientation, move);
        }
        score--;
    }

    //TODO something?
    public void moveFailed() {
        ;
    }

    void setArmed(boolean b) {
        this.isArmed = b;
    }

    public boolean isInLineOfSight(int otherRow, int otherCol) {
        int r = getRow(), c = getCol();
        if (r == otherRow) {
            while (!Enviroment.env.map[r][c].isWall()) {
                if (c < otherCol) {
                    c++;
                } else if (c > otherCol) {
                    c--;
                } else {//if(c == other.getCol())
                    //System.out.println("============== isInLineOfSight on row "+r+" BOOM! on col "+c);
                    return true;
                }
            }
            //System.out.println("==============  isInLineOfSight on row "+r+" has hit a wall on col "+c);
        }
        else if (c == otherCol) {
            while (!Enviroment.env.map[r][c].isWall()) {
                if (r < otherRow) {
                    r++;
                } else if (r > otherRow) {
                    r--;
                } else {//if(c == other.getCol())
                    //System.out.println("============== isInLineOfSight on col "+c+" BOOM! on row "+r);
                    return true;
                }
            }
            //System.out.println("============== isInLineOfSight on col "+c+" has hit a wall on row "+r);
        }
        
        return false;
    }

    public boolean isInLineOfSight(Agent other) {
        return this.isInLineOfSight(other.getRow(), other.getCol());
    }

    @Override
    public String toString() {
        return "Agent "+getName()+": pos=" + row + "," + col + " " + orientation + "   score="+score;
    }
    
    
}
